
--[[
	这里Entry只当做一个数据结构，不加入具体的业务逻辑
]]
local Entry = class("Entry")

function Entry:ctor(  )
	self.__isEntry = true
	self._autoRelease = true
	self._retain = 0
	self:initEntry()
end

function Entry:retain()
	self._retain = self._retain + 1
	self._autoRelease = false
end

function Entry:release( ... )
	self._retain = self._retain - 1
	if self._retain <= 0 then
		self._retain = 0
		self._autoRelease = true
	end
end

function Entry:initEntry( ... )
	self._queueList = {} --顺序播放列表
	self._parallelList = {} --及时播放列表
end

--添加到串行列表（队列顺序执行）
function Entry:addToQueue(entry, stepFunc)
	if self._queueList == nil then return end
	assert(type(stepFunc) == "function","stepFunc must be function ")
	--顺序播放运算支持添加相同的步进函数（按顺序执行不影响）
	self._queueList[#self._queueList+1] = {entry = entry,stepFunc = stepFunc}
end

--添加到并行列表（即时执行）
function Entry:addToParallel(entry,stepFunc)
	if self._parallelList == nil then return end
	assert(type(stepFunc) == "function","stepFunc must be function ")
	local finded = false
	for i=1,#self._parallelList do
		local item = self._parallelList[i]
		if item.entry == entry and stepFunc == item.stepFunc then
			finded = true
			break
		end
	end
	--及时队列运算不允许添加相同的步进函数（这样一来同一帧会执行多次）
	if finded == true then
		Error("Entry:addToParallel finded = ",finded)
		return
	end
	self._parallelList[#self._parallelList+1] = {entry = entry,stepFunc = stepFunc}
end

--[[
	是否执行完毕
]]
function Entry:isDone( ... )
	-- body
	local isQueueDone = self._queueList == nil or #self._queueList < 1
	local isParallelDone = self._parallelList == nil or #self._parallelList < 1
	return isQueueDone and isParallelDone
end

--Entry的默认更新函数
function Entry:updateEntry( dt )
	if self:isDone() then return true end
	--并发执行
	local doneList = nil
	local listIndex = 1
	while self._parallelList and listIndex <= #self._parallelList  do
		local item = self._parallelList[listIndex]
		local isFinish = item.stepFunc(item.entry,dt)
		if isFinish == true then
			--标记执行完毕的entry下标
			doneList = doneList or {}
			doneList[#doneList+1] = listIndex
		end
		listIndex = listIndex + 1
	end

	if doneList ~= nil and self._parallelList then
		for i=#doneList,1,-1 do
			local index = doneList[i]
			if self._parallelList then
				table.remove(self._parallelList,index)
			end
		end
	end
	
	--顺序执行(从第一个开始直到结束然后顺序执行下一个)
	local first = self._queueList and self._queueList[1]
	while first ~= nil do
		local entry = first.entry
		local stepFunc = first.stepFunc
		local isFinish = stepFunc(entry,dt)

		--机制修改，在上面的stepFunc里可能会把当前entry清空，再添加新的entry，但是在函数最后可能会返回true，导致把新的entry直接移除，新加个一致判断
		local nowFirst = self._queueList and self._queueList[1]
		if nowFirst ~= first then
			isFinish = false
		end

		if isFinish == true then
			if self._queueList then
				table.remove(self._queueList,1)
				first = self._queueList[1]
			else
				break
			end
		else
			break
		end
	end

	local isDone = self:isDone()
	if isDone and self._autoRelease then
		--只有串行、和并行两个列表都执行完毕后才可以释放
		-- Trace("destroyEntry ==== ",self.__cname)
		self:destroyEntry()
	end

	return isDone
end

function Entry:clearAll( ... )
	-- body
	local cache = {}
	local function addToClear( list )
		if list == nil or #list < 1 then return end
		for i=#list,1,-1 do
			local item = list[i]
			local entry = item.entry
			if entry ~= nil and entry.__isEntry and entry ~= self then
				--这里如果entry == self 不能加入到释放队列以免多次释放造成问题
				local bool = table.indexof(cache,entry)
				if bool == false then
					cache[#cache+1] = entry
				end
			end
			table.remove(list,i)
		end
	end

	addToClear(self._queueList)
	addToClear(self._parallelList)

	for i=#cache,1,-1 do
		cache[i]:destroyEntry()
		table.remove(cache,i)
	end
	cache = nil
end

function Entry:destroyEntry( ... )
	self:clearAll()
	self._queueList = nil
	self._parallelList = nil
end

return Entry